home *** CD-ROM | disk | FTP | other *** search
/ Power Programmierung / Power-Programmierung (Tewi)(1994).iso / magazine / msysjour / vol06 / 01 / kermit / wntint.c < prev    next >
C/C++ Source or Header  |  1990-12-31  |  11KB  |  337 lines

  1. /*
  2.  * WNTERM initialization module
  3.  *
  4.  * Written by
  5.  * William S. Hall
  6.  * 3665 Benton Street, #66
  7.  * Santa Clara, CA 95051
  8. */
  9.  
  10. #define NOMINMAX
  11. #define NOATOM
  12. #define NOKANJI
  13. #define NOSOUND
  14. #include <windows.h>
  15. #include <limits.h>
  16. #include <string.h>
  17. #include <stdlib.h>
  18. #include <ascii.h>
  19. #include "ttycls.h"
  20. #include "wnterm.h"
  21.  
  22. /* local function declarations */
  23. static BOOL NEAR RegisterMainWindowClass(HANDLE);
  24. static void NEAR GetPrevInstanceData(HANDLE);
  25. static HWND NEAR MakeAndShowMainWnd(HANDLE, int);
  26. static BOOL NEAR OpenAndSetCommPort(HANDLE);
  27. static BOOL NEAR SearchKey(char *str, char *key, int len);
  28. short FAR PASCAL FindSmallFont(LPLOGFONT, LPTEXTMETRIC, short, LPSTR);
  29.  
  30. /* this function calls all initialization routines */
  31. BOOL FAR InitProgram(hInstance,hPrevInstance, lpszCmdLine, cmdShow)
  32. HANDLE hInstance, hPrevInstance;
  33. LPSTR lpszCmdLine;
  34. int cmdShow;
  35. {
  36.  
  37.     hInst = hInstance;        // need this value in various places
  38.  
  39.   // if first instance, register windows and get string for icon.
  40.   // otherwise, just load data normally obtained during registration.
  41.     if (!hPrevInstance) {
  42.         LoadString(hInstance,IDS_ICONSTRING,(LPSTR)szIconTitle,
  43.             sizeof(szIconTitle));
  44.     if (!RegisterMainWindowClass(hInstance))
  45.         return FALSE;
  46.     }
  47.     else
  48.     GetPrevInstanceData(hPrevInstance);
  49.  
  50.   // now create and show the main window.
  51.     if (!MakeAndShowMainWnd(hInstance,cmdShow))
  52.     return FALSE;
  53.  
  54.   // Activate the local/line menu selection to put the terminal on line
  55.     SendMessage(MWnd.hWnd, WM_COMMAND, IDM_OFFLINE,0L);
  56.  
  57.   // open the communications port.
  58.     if (!OpenAndSetCommPort(hInstance))
  59.     PostMessage(MWnd.hWnd, WM_SYSCOMMAND, SC_CLOSE, 0L);
  60.  
  61.     return TRUE;
  62. }
  63.  
  64. /* register the main window */
  65. static BOOL NEAR RegisterMainWindowClass(HANDLE hInstance)
  66. {
  67.  
  68.     WNDCLASS WndClass;
  69.  
  70.   // get the class name from the resource segment.
  71.     LoadString(hInstance,IDS_APPNAME,(LPSTR)szAppName,sizeof(szAppName));
  72.  
  73.   // clear the WndClass data area
  74.     memset(&WndClass,0, sizeof(WndClass));
  75.  
  76.   // fill in the data.
  77.     WndClass.hCursor    = LoadCursor(NULL, IDC_ARROW);
  78.     WndClass.hIcon    = NULL;            // no icon bitmap.
  79.     WndClass.lpszMenuName = (LPSTR)szAppName;    // use this menu.
  80.     WndClass.lpszClassName = (LPSTR)szAppName;    // this class
  81.     WndClass.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); // let Windows do it
  82.     WndClass.hInstance = hInstance;        // this instance
  83.     WndClass.style = CS_VREDRAW | CS_HREDRAW;    // basic style
  84.     WndClass.lpfnWndProc = MainWndProc;        // window proc
  85.     WndClass.cbWndExtra = sizeof(PTTYWND);    // data associated with window
  86.     if (!RegisterClass((LPWNDCLASS)&WndClass))
  87.     return FALSE;
  88.  
  89.   // show success.
  90.     return TRUE;
  91.  
  92. }
  93.  
  94. /* if we don't need to register the window, we have to load these strings */
  95. static void NEAR GetPrevInstanceData(HANDLE hPrevInstance)
  96. {
  97.  
  98.     GetInstanceData(hPrevInstance, (PSTR)szAppName, sizeof(szAppName));
  99.     GetInstanceData(hPrevInstance, (PSTR)szIconTitle, sizeof(szIconTitle));
  100. }
  101.  
  102. /* make the main window */
  103. static HWND NEAR MakeAndShowMainWnd(hInstance, cmdShow)
  104. HANDLE hInstance;
  105. int cmdShow;
  106. {
  107.  
  108.     char szWinTitle[50];
  109.  
  110.   // get the title from the resource segment.
  111.     LoadString(hInstance, IDS_WINTITLE, (LPSTR)szWinTitle,sizeof(szWinTitle));
  112.  
  113.   // create the window.
  114.     MWnd.hWnd = CreateWindow((LPSTR)szAppName,        // class
  115.                  (LPSTR)szWinTitle,        // title
  116.                  WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN,
  117.                  CW_USEDEFAULT,0,        // default position
  118.                  CW_USEDEFAULT,0,        // and size
  119.                  (HWND)NULL,        // no parent
  120.                  (HMENU)NULL,        // class menu
  121.                  (HANDLE)hInstance,        // instance
  122.                  (LPSTR)&MWnd);        // extra create data
  123.  
  124.   // continue if window created and text buffer initialized.
  125.     if (MWnd.hWnd && MWnd.hVidBuf) {
  126.     ShowWindow(MWnd.hWnd, cmdShow);        // show window
  127.         UpdateWindow(MWnd.hWnd);        // paint it
  128.     return MWnd.hWnd;            // show success
  129.     }
  130.     return NULL;            // show failure
  131. }
  132.  
  133. static LOGFONT *pttyfat; // used to find a small font if requested in win.ini
  134.  
  135. /* 
  136.  * this function is called by Windows until all fonts of the specified
  137.  * type have been enumerated.
  138.  */
  139. short FAR PASCAL FindSmallFont(lpLF, lpTM, type, lpData)
  140. LPLOGFONT lpLF;
  141. LPTEXTMETRIC lpTM;
  142. short type;
  143. LPSTR lpData;
  144. {
  145.  
  146.     register int i;
  147.     static short refheight = 0;
  148.     short refwidth = (short)LOWORD(lpData);
  149.     short height = lpTM->tmHeight + lpTM->tmExternalLeading;
  150.     short width = lpTM->tmAveCharWidth;
  151.  
  152.   // lpData contains the width and height of the system font, which is used
  153.   // as a reference value.  On the first pass, it must be initialized.
  154.     if (refheight == 0)
  155.     refheight = HIWORD(lpData);
  156.  
  157.   // if we find a smaller font, get its paramters.
  158.     if ((height < refheight) && (width <= refwidth)) {
  159.     refheight = height;
  160.     pttyfat->lfHeight = lpLF->lfHeight;
  161.     pttyfat->lfWidth = lpLF->lfWidth;
  162.     pttyfat->lfWeight = lpLF->lfWeight;
  163.     pttyfat->lfCharSet = lpLF->lfCharSet;
  164.     pttyfat->lfOutPrecision = lpLF->lfOutPrecision;
  165.     pttyfat->lfClipPrecision = lpLF->lfClipPrecision;
  166.     pttyfat->lfQuality = lpLF->lfQuality;
  167.     pttyfat->lfPitchAndFamily = lpLF->lfPitchAndFamily;
  168.     for (i = 0; i < LF_FACESIZE; i++)
  169.         pttyfat->lfFaceName[i] = lpLF->lfFaceName[i];
  170.     }
  171.     return refheight;
  172. }
  173.  
  174. /* called when main window created */
  175. void WndCreate(HWND hWnd, LPCREATESTRUCT pCS)
  176. {
  177.  
  178.     short width, height, cwidth, cheight;
  179.     TEXTMETRIC TM;
  180.     HDC hDC;
  181.     PTTYWND pMWnd;
  182.     FARPROC fp;
  183.     short result;
  184.     char valstr[80], keystr[20], defstr[20];
  185.     int initlen;
  186.     HFONT holdfont;
  187.  
  188.   // If the communications port is open, cid >= 0.  If we see that cid 
  189.   // is a large negative number, then we know the comm port is not open.
  190.     cid = INT_MIN;
  191.  
  192.   // get off/on-line menu strings for later use.
  193.     LoadString(hInst, IDS_OFFLINE, (LPSTR)szOffLine,sizeof(szOffLine));
  194.     LoadString(hInst, IDS_ONLINE, (LPSTR)szOnLine,sizeof(szOnLine));
  195.  
  196.   // Create a farproc to the main window procedure.
  197.     fpMainWndProc = MakeProcInstance((FARPROC)MainWndProc, hInst);
  198.  
  199.   // we are going to create a buffer for a window this large.
  200.     width = GetSystemMetrics(SM_CXFULLSCREEN);
  201.     height = GetSystemMetrics(SM_CYFULLSCREEN) - GetSystemMetrics(SM_CYMENU);
  202.  
  203.   // Read win.ini to see if the small font should be used.
  204.   // If there is no win.ini entry, make one first.
  205.     initlen = GetProfileString(szAppName, NULL, "", valstr, sizeof(valstr));
  206.     itoa(smallfont, defstr, 10);    
  207.     LoadString(hInst,IDS_SMALLFONT,(LPSTR)keystr,sizeof(keystr));
  208.     if (!SearchKey(valstr, keystr, initlen)) {
  209.         WriteProfileString(szAppName, keystr, defstr);
  210.         SendMessage((HWND)-1, WM_WININICHANGE, 0, (LONG)(LPSTR)szAppName);
  211.     }
  212.     smallfont = GetProfileInt(szAppName, keystr, smallfont);
  213.  
  214.   // Get screen device context
  215.     hDC = GetDC(hWnd);
  216.  
  217.   // If the small font is requested, enumerate all fonts
  218.   // and pick the one with fixed pitch and the smallest height.
  219.     if (smallfont) {
  220.     pttyfat = (LOGFONT *)LocalAlloc(LPTR, sizeof(LOGFONT));
  221.         LoadString(hInst, IDS_FONTFACE, (LPSTR)valstr, sizeof(valstr));
  222.         fp = MakeProcInstance((FARPROC)FindSmallFont, hInst);
  223.         result = EnumFonts(hDC, valstr, fp, (LPSTR)MAKELONG(cwidth, cheight));
  224.         if ((result > 0) && (cheight - result))        // found one
  225.         hfont = CreateFontIndirect(pttyfat);
  226.     FreeProcInstance(fp);
  227.     LocalFree((HANDLE)pttyfat);
  228.     }
  229.     else
  230.       // use the system font
  231.         hfont = GetStockObject(SYSTEM_FIXED_FONT);
  232.  
  233.   //  Get size
  234.     holdfont = SelectObject(hDC, hfont);
  235.     GetTextMetrics(hDC, &TM);
  236.     cwidth = TM.tmAveCharWidth;
  237.     cheight = TM.tmHeight + TM.tmExternalLeading;
  238.     SelectObject(hDC, holdfont);
  239.  
  240.     ReleaseDC(hWnd, hDC);
  241.  
  242.   // here we retrieve the pointer to our local window stucture.
  243.     pMWnd = (PTTYWND)LOWORD(pCS->lpCreateParams);
  244.  
  245.   // set the extra data to be the pointer to the TWnd structure.
  246.     SetWindowWord(hWnd,0,(WORD)pMWnd);
  247.  
  248.   // now create the text buffer and set some defaults.
  249.     InitTTYWindow(pMWnd,0,0,width,height,cwidth,cheight,
  250.                 FALSE,FALSE,TRUE,(WORD)hfont,0x7f);
  251. }
  252.  
  253. /* open a communications port */
  254. static BOOL NEAR OpenAndSetCommPort(hInstance)
  255. HANDLE hInstance;
  256. {
  257.     register int i;
  258.     char modestr[40];
  259.     char commstr[40];
  260.     char errorstr[80];
  261.     char appstr[10];
  262.     int reply;
  263.  
  264.     for (i = 0; i < MAXCOMMPORTS; i++) {
  265.         LoadString(hInstance, IDS_COM1 + i, (LPSTR)commstr, sizeof(commstr));
  266.         if ((cid = OpenComm((LPSTR)commstr,INQUESIZE,OUTQUESIZE)) < 0) {
  267.             LoadString(hInstance, IDS_CANNOTOPENFIRSTPORT, (LPSTR)errorstr,
  268.                 sizeof(errorstr));
  269.         reply = MessageBox(MWnd.hWnd, (LPSTR)errorstr, (LPSTR)commstr,
  270.                 MB_OKCANCEL | MB_ICONQUESTION);
  271.         if (reply == IDCANCEL)
  272.             return FALSE;
  273.     }
  274.     else
  275.         break;
  276.     }
  277.  
  278.     if (i == MAXCOMMPORTS) {
  279.         ShowMessage(MWnd.hWnd, IDS_CANNOTOPENANYPORT);
  280.     return FALSE;
  281.     }
  282.  
  283.   // we opened a port, so we will attach the port name to the title.
  284.     GetWindowText(MWnd.hWnd, (LPSTR)modestr, sizeof(modestr));
  285.     strcat(modestr, commstr);
  286.     SetWindowText(MWnd.hWnd, (LPSTR)modestr);        
  287.  
  288.   // now read in the device control block.
  289.     if (GetCommState(cid, (DCB FAR *)&CommData) >= 0) {
  290.      // read win.ini to find out how to set the port.
  291.     LoadString(hInstance, IDS_PORTSECTION, (LPSTR)appstr, sizeof(appstr));
  292.     GetProfileString((LPSTR)appstr,(LPSTR)commstr,(LPSTR)"",
  293.             (LPSTR)modestr,sizeof(modestr));
  294.      // concatenate the comm data to the name of the port.
  295.         strcat(commstr, modestr);
  296.      // build the DCB according to commstr.
  297.         if (BuildCommDCB((LPSTR)commstr, (DCB FAR *)&CommData) >= 0) {
  298.       // modify some additional DCB fields.
  299.         CommData.XonLim = INQUESIZE / 8;    // Low water mark
  300.         CommData.XoffLim = INQUESIZE / 8;    // High water mark
  301.         CommData.fNull = TRUE;        // ignore null data
  302.         CommData.XonChar = XON;        // use ^Q for xon
  303.         CommData.XoffChar = XOFF;        // use ^S for xoff
  304.         CommData.fOutX = TRUE;        // set outbound flow control
  305.         CommData.fInX = TRUE;        // set inbound flow control
  306.       // finally, set the values.
  307.         if (SetCommState ((DCB FAR *)&CommData) >= 0)
  308.             return TRUE;
  309.     }
  310.     }
  311.   // everything failed, close the comm port and quit.
  312.     ShowMessage(MWnd.hWnd, IDS_COMMSETERROR);
  313.     CloseComm(cid);
  314.     return FALSE;
  315. }
  316.  
  317. /* Search the keystring buffer for 'key'. Keystrings are delimited by 0's */
  318. static BOOL NEAR SearchKey(char *str, char *key, int len)
  319. {
  320.  
  321.     register int i;
  322.     register char *startptr;
  323.     startptr = str;
  324.  
  325.     for (i = 0; i < len; i++) {
  326.     if (*str++)
  327.         ;
  328.     else {
  329.         if (strcmp(key, startptr) == 0)
  330.         return(TRUE);
  331.         startptr = str;
  332.     }
  333.     }
  334.     return (FALSE);
  335.  
  336. }
  337.